package com.oauth.google.server.service;

import java.net.URL;
import java.util.List;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.google.gdata.client.authn.oauth.GoogleOAuthHelper;
import com.google.gdata.client.authn.oauth.GoogleOAuthParameters;
import com.google.gdata.client.authn.oauth.OAuthHmacSha1Signer;
import com.google.gdata.client.authn.oauth.OAuthSigner;
import com.google.gdata.client.docs.DocsService;
import com.google.gdata.data.IFeed;
import com.google.gdata.data.docs.DocumentListEntry;
import com.google.gdata.data.docs.DocumentListFeed;
import com.oauth.google.client.beans.docs.GoogleDocument;
import com.oauth.google.server.conf.DocsInfoBean;
import com.oauth.google.server.conf.GoogleOAuthConfig;
import com.oauth.google.server.constants.GoogleServiceType;
import com.oauth.google.server.shared.GoogleDocUtil;
import com.oauth.service.application.ApplicationService;
import com.oauth.service.global.beans.OAuthAccessToken;

@Service
public class DocsOAuthServiceImpl extends AbstractGoogleOAuthService implements DocsOAuthService {

	private GoogleOAuthHelper oauthHelper;
	private OAuthSigner signer;

	@Autowired
	private ApplicationService applicationService;

	@Autowired
	@Qualifier("docsConfig")
	private GoogleOAuthConfig oauthConfigBean;

	@Autowired
	private DocsInfoBean docsInfoBean;

	@PostConstruct
	public void initialise() {
		signer = new OAuthHmacSha1Signer();
		oauthHelper = new GoogleOAuthHelper(signer);
	}

	/**
	 * @param applicationService
	 *            the applicationService to set
	 */
	public void setApplicationService(ApplicationService applicationService) {
		this.applicationService = applicationService;
	}

	/**
	 * @param pOAuthConfigBean
	 *            the oAuthConfigBean to set
	 */
	public void setOAuthConfigBean(GoogleOAuthConfig pOAuthConfigBean) {
		oauthConfigBean = pOAuthConfigBean;
	}

	/**
	 * @return the oauthConfigBean
	 */
	public GoogleOAuthConfig getOAuthConfigBean() {
		return oauthConfigBean;
	}

	private DocsService getDocService(Long pMemberId) throws Exception {
		GoogleOAuthParameters oauthParameters = getOAuthParameters();
		OAuthAccessToken accessToken = getAccessTokenFromDB(pMemberId);
		oauthParameters.setOAuthToken(accessToken.getToken());
		oauthParameters.setOAuthTokenSecret(accessToken.getTokenSecret());

		DocsService docService = new DocsService(GoogleServiceType.Docs.getGoogleServiceName());
		// Set the OAuth credentials which were obtained from the step
		docService.setOAuthCredentials(oauthParameters, signer);
		return docService;
	}

	private <F extends IFeed> F getFeed(DocsService pDocsService, Class<F> pClass) throws Exception {
		URL feedUrl = new URL(GoogleServiceType.Docs.getFeedUrl());
		return pDocsService.getFeed(feedUrl, pClass);
	}

	@Override
	public List<GoogleDocument> getDocuments(Long pMemberId) throws Exception {
		DocsService docService = getDocService(pMemberId);
		DocumentListFeed feed = getFeed(docService, DocumentListFeed.class);
		List<DocumentListEntry> entries = feed.getEntries();
		return GoogleDocUtil.convertToEntries(entries);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.oauth.google.server.service.AbstractGoogleService#getApplicationKey()
	 */
	@Override
	protected Long getApplicationKey() {
		return docsInfoBean.getKey();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.oauth.google.server.service.AbstractGoogleService#getApplicationService
	 * ()
	 */
	@Override
	protected ApplicationService getApplicationService() {
		return applicationService;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.oauth.google.server.service.AbstractGoogleService#getScope()
	 */
	@Override
	protected String getScope() {
		return GoogleServiceType.Docs.getScope();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.oauth.google.server.service.AbstractGoogleService#getOAuthHelper()
	 */
	@Override
	protected GoogleOAuthHelper getOAuthHelper() {
		return oauthHelper;
	}

}
